package org.irri.smta.ui.bean;

import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletContext;

import org.apache.commons.lang.StringUtils;
import org.irri.smta.common.Constants;
import org.irri.smta.domain.ReportLog;
import org.irri.smta.domain.SmtaReport;
import org.irri.smta.service.IReportLogService;
import org.irri.smta.service.ISmtaGenerateService;
import org.irri.smta.service.ISmtaReportService;
import org.irri.smta.util.BeanUtils;
import org.irri.smta.util.ConverterUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Named("generatorBean")
@ViewScoped
public class GeneratorBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private static final Logger LOGGER = LoggerFactory
			.getLogger(GeneratorBean.class);

	private static final String PDF_COPY_DIR = "files";
	
	@Inject
	@Named("loginBean")
	private LoginBean loginBean;

	@Inject
	@Named("resourceConfigBean")
	private ResourceConfigBean resourceConfigBean;

	@Inject
	@Named("fileLinkBean")
	private FileLinkBean fileLinkBean;

	@Inject
	@Named("smtaReportService")
	private ISmtaReportService<SmtaReport, Long> smtaReportService;

	@Inject
	@Named("smtaGenerateService")
	private ISmtaGenerateService<SmtaReport, Long> smtaGenerateService;

	@Inject
	@Named("reportLogService")
	private IReportLogService<ReportLog, Long> reportLogService;

	private String smtaId;
	private String shuRequestId;
	private String mtaType = Constants.MTA_TYPE_0;
	private String viewName;
	private Integer progress = 0;
	private BeanUtils beanUtils = new BeanUtils();

	public GeneratorBean() {
		super();
		setViewName(Constants.GENERATOR_VIEW_NAME);
	}

	@PostConstruct
	public void init() {
		LOGGER.debug("init()");
	}

	public void preRenderView() {
		LOGGER.debug("preRenderView()");
		if (beanUtils.getSessionUser() == null) {
			loginBean.defaultLogin();
		}
		if (!beanUtils.validateUser()) {
			beanUtils.navigateToView(Constants.LOGIN_VIEW_NAME);
		}
	}

	public void onComplete() {
		if (progress == 100) {
			beanUtils.updateInfoMessage("Completed.", "SMTA Generated.");
		} else {
			beanUtils.updateInfoMessage("Failed.", "Failed generating SMTA!");
		}
	}

	public void generate() {
		progress = 0;
		if (!StringUtils.isEmpty(getSmtaId())
				&& !StringUtils.isEmpty(getShuRequestId())) {
			generatePdf(getMtaType(), getSmtaId(), getShuRequestId());
			beanUtils.navigateToPopupView(Constants.FILE_LINK_VIEW_NAME + ".jsf");
		} else {
			progress = 0;
		}
	}

	public void generatePdf(String mtaType, String smtaId, String shuRequestId) {
		LOGGER.info("Generating PDF for SMTA ID = " + smtaId + " and SHU REQUEST ID = " + shuRequestId);
		Map<String, String> paramMap = new HashMap<String, String>();
		String smtaTemplateDirectory = resourceConfigBean.getSmtaTemplateDirectory();
		String smtaTemplateFilename = resourceConfigBean.getSmtaTemplateFilename() + Constants.TEMPLATE_EXTENSION;
		String smtaGeneratedDirectory = resourceConfigBean.getGeneratedDirectory();
		String smtaGeneratedFilename = smtaId + Constants.PDF_EXTENSION;
		String mtaTemplateDirectory = resourceConfigBean.getMtaTemplateDirectory();
		String mtaTemplateFilename = resourceConfigBean.getMtaTemplateFilename() + mtaType + Constants.TEMPLATE_EXTENSION;
		String mtaGeneratedDirectory = resourceConfigBean.getGeneratedDirectory();
		String mtaGeneratedFilename = smtaId + Constants.MTA_SUFFIX + Constants.PDF_EXTENSION;
		String smtaWebsiteUrl = resourceConfigBean.getUrlSmtaWebsite();
		
		paramMap.put(Constants.KEY_SMTA_TEMPLATE_DIRECTORY, smtaTemplateDirectory);
		paramMap.put(Constants.KEY_SMTA_TEMPLATE_FILENAME, smtaTemplateFilename);
		paramMap.put(Constants.KEY_MTA_TEMPLATE_DIRECTORY, mtaTemplateDirectory);
		paramMap.put(Constants.KEY_MTA_TEMPLATE_FILENAME, mtaTemplateFilename);
		paramMap.put(Constants.KEY_SMTA_GENERATED_DIRECTORY, smtaGeneratedDirectory);
		paramMap.put(Constants.KEY_SMTA_GENERATED_FILENAME, smtaGeneratedFilename);
		paramMap.put(Constants.KEY_MTA_GENERATED_DIRECTORY, mtaGeneratedDirectory);
		paramMap.put(Constants.KEY_MTA_GENERATED_FILENAME, mtaGeneratedFilename);
		paramMap.put(Constants.KEY_IRRI_SMTA_ID, smtaId);
		paramMap.put(Constants.KEY_SHU_REQUEST_ID, shuRequestId);
		paramMap.put(Constants.KEY_SMTA_WEBSITE_URL, smtaWebsiteUrl);
		
		try {
			fileLinkBean.setSmtaFileUrl("#");
			smtaGenerateService.generatePdf(paramMap, Constants.MTA_TYPE_0);
			copyGeneratedFile(smtaGeneratedDirectory, smtaGeneratedFilename, 0);
			fileLinkBean.setSmtaFileUrl(PDF_COPY_DIR + "/" + smtaGeneratedFilename);
			LOGGER.info("PDF file URL: " + fileLinkBean.getSmtaFileUrl());
			
			fileLinkBean.setMtaFileUrl("#");
			if (!mtaType.equalsIgnoreCase(Constants.MTA_TYPE_0)) {
				smtaGenerateService.generatePdf(paramMap, mtaType);
				copyGeneratedFile(mtaGeneratedDirectory, mtaGeneratedFilename, 1);
				fileLinkBean.setMtaFileUrl(PDF_COPY_DIR + "/" + mtaGeneratedFilename);
				LOGGER.info("PDF file URL: " + fileLinkBean.getMtaFileUrl());
			}
		} catch (Exception e) {
			// Add exception to report log
			reportLogService.addReportLog(e.getMessage());
			LOGGER.error(e.getMessage());
		}
		setProgress(100);
	}

	private void copyGeneratedFile(String generatedDirectory, String generatedFilename, int index) {
		ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
		String generatedFilepath = generatedDirectory + "/" + generatedFilename;
		File generatedFile = new File(generatedFilepath);
		LOGGER.info("Generated file path: " + generatedFilepath);
		
		String fileDirectory = servletContext.getRealPath("/");
		String linkFilepath = fileDirectory + PDF_COPY_DIR + "/" + generatedFilename;
		File linkFile = new File(linkFilepath);
		LOGGER.info("Link file path: " + linkFilepath);

		try {
			LOGGER.info("Copying file from generated file path to link file path.");
			ConverterUtils.copy(generatedFile, linkFile);
		} catch (Exception e) {
			// Add exception to report log
			reportLogService.addReportLog(e.getMessage());
			LOGGER.error(e.getMessage());
		}
	}

	public String getMtaType() {
		return mtaType;
	}

	public void setMtaType(String mtaType) {
		this.mtaType = mtaType;
	}

	public String getSmtaId() {
		return smtaId;
	}

	public void setSmtaId(String smtaId) {
		this.smtaId = smtaId;
	}

	public String getShuRequestId() {
		return shuRequestId;
	}

	public void setShuRequestId(String shuRequestId) {
		this.shuRequestId = shuRequestId;
	}

	public String getViewName() {
		return viewName;
	}

	public void setViewName(String viewName) {
		this.viewName = viewName;
	}

	public Integer getProgress() {
		if (progress == null) {
			progress = 0;
		} else {
			if (progress > 100) {
				progress = 100;
			}
		}

		return progress;
	}

	public void setProgress(Integer progress) {
		this.progress = progress;
	}

}
